<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>拖拽上传示例</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
    <style>
      #dropArea {
        width: 300px;
        height: 300px;
        border: 1px dashed gray;
        margin-bottom: 20px;
      }
      #dropArea p {
        text-align: center;
        color: #999;
      }
      #dropArea.highlighted {
        background-color: #ddd;
      }
      #imagePreview {
        max-height: 250px;
        overflow-y: scroll;
      }
      #imagePreview img {
        width: 100%;
        display: block;
        margin: auto;
      }
    </style>
  </head>
  <body>
    <h3>拖拽上传示例</h3>
    <div id="dropArea">
      <p>拖拽上传文件</p>
      <div id="imagePreview"></div>
    </div>
    <script>
      const dropAreaEle = document.querySelector("#dropArea");
      const imgPreviewEle = document.querySelector("#imagePreview");
      const IMAGE_MIME_REGEX = /^image\/(jpe?g|gif|png)$/i;

      // 阻止默认拖拽行为
      ["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
        dropAreaEle.addEventListener(eventName, preventDefaults, false);
        document.body.addEventListener(eventName, preventDefaults, false);
      });

      // 切换目标区域的高亮状态
      ["dragenter", "dragover"].forEach((eventName) => {
        dropAreaEle.addEventListener(eventName, highlight, false);
      });
      ["dragleave", "drop"].forEach((eventName) => {
        dropAreaEle.addEventListener(eventName, unhighlight, false);
      });

      function preventDefaults(e) {
        e.preventDefault();
        e.stopPropagation();
      }

      function highlight(e) {
        dropAreaEle.classList.add("highlighted");
      }

      function unhighlight(e) {
        dropAreaEle.classList.remove("highlighted");
      }

      dropAreaEle.addEventListener("drop", handleDrop, false);

      function handleDrop(e) {
        const dt = e.dataTransfer;
        const files = [...dt.files];
        files.forEach((file) => {
          previewImage(file, imgPreviewEle);
        });
        files.forEach((file) => {
          upload({
            url: "/single",
            file,
          });
        });
      }

      function previewImage(file, container) {
        if (IMAGE_MIME_REGEX.test(file.type)) {
          const reader = new FileReader();
          reader.onload = function (e) {
            let img = document.createElement("img");
            img.src = e.target.result;
            container.append(img);
          };
          reader.readAsDataURL(file);
        }
      }

      const request = axios.create({
        baseURL: "http://localhost:3000/upload",
        timeout: 60000,
      });

      function upload({ url, file, fieldName = "file" }) {
        let formData = new FormData();
        formData.set(fieldName, file);
        request.post(url, formData, {
          // 监听上传进度
          onUploadProgress: function (progressEvent) {
            const percentCompleted = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );
            console.log(percentCompleted);
          },
        });
      }
    </script>
  </body>
</html>
